package com.populatton.common;

import com.populatton.base.BaseWrappers;
import com.populatton.base.RespEnum;
import com.populatton.common.RevertException;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.HttpStatus;
import org.springframework.http.converter.HttpMessageNotReadableException;
import org.springframework.validation.BindException;
import org.springframework.web.HttpMediaTypeException;
import org.springframework.web.HttpRequestMethodNotSupportedException;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.MissingServletRequestParameterException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseStatus;
import org.springframework.web.bind.annotation.RestControllerAdvice;
import org.springframework.web.servlet.NoHandlerFoundException;

import java.lang.reflect.UndeclaredThrowableException;

/**
* description:
* @date: 2019/7/6
* @param:
* @return:
 */
@Slf4j
@RestControllerAdvice
public class MyExceptionHandler {

	/**
	 *  默认的异常处理
	 * @author Flying
	 * @param e
	 * @return
	 */
	@ExceptionHandler(Exception.class)
	public BaseWrappers<String> revertException(Exception e) {
		if(log.isErrorEnabled()) {
			log.error(RespEnum.SERVER_ERROR.getDesc(), e);
		}
		return new BaseWrappers<>(RespEnum.SERVER_ERROR.getCode(),RespEnum.SERVER_ERROR.getDesc());
	}

	/**
	 * 监听RevertException异常 统一处理
	 */
	@ExceptionHandler(RevertException.class)
	public BaseWrappers<String> revertExceptionHandler(RevertException e) {
		return new BaseWrappers<>(e.getCode(),e.getMessage());
	}


	/**
	 * 监听参数绑定异常 并处理
	 * @param e
	 * @return
	 */
	@ExceptionHandler(BindException.class)
	@ResponseStatus(HttpStatus.FORBIDDEN)
	public BaseWrappers<String> bindExceptionHandler(BindException e) {

		if(log.isInfoEnabled()){
			log.info("错误信息：{}", e.getBindingResult().getFieldError().getDefaultMessage());
		}
		return new BaseWrappers<>(RespEnum.REQUEST_PARAM_ERROR.getCode(),e.getBindingResult().getFieldError().getDefaultMessage());
	}


	/**
	 * Spring 参数绑定异常
	 * @param e
	 * @return
	 */
	@ExceptionHandler(MissingServletRequestParameterException.class)
	public BaseWrappers<String> missingServletRequestParameterExceptionHandler(MissingServletRequestParameterException e) {
		if(log.isInfoEnabled()){
			log.info(e.getParameterName()+"不能为空");
		}
		return new BaseWrappers<>(RespEnum.REQUEST_PARAM_ERROR.getCode(),e.getParameterName()+"不能为空");
	}

	/**
	 * 非法参数验证异常
	 * @param e
	 * @return
	 */
	@ExceptionHandler(MethodArgumentNotValidException.class)
	public BaseWrappers<String> methodArgumentNotValidExceptionExceptionHandler(MethodArgumentNotValidException e) {
		if(log.isInfoEnabled()){
			log.info(e.getBindingResult().getFieldError().getDefaultMessage()+"不能为空");
		}
		return new BaseWrappers<>(RespEnum.REQUEST_PARAM_ERROR);
	}


	@ExceptionHandler(HttpRequestMethodNotSupportedException.class)
	@ResponseStatus(HttpStatus.METHOD_NOT_ALLOWED)
	public BaseWrappers<String> httpRequestMethodNotSupportedException(HttpRequestMethodNotSupportedException e) {
		if(log.isErrorEnabled()) {
			log.error(RespEnum.SERVER_ERROR.getDesc(), e);
		}
		return new BaseWrappers<>(RespEnum.SYSTEM_AUTHENTICATION);
	}

	@ExceptionHandler(UndeclaredThrowableException.class)
	public BaseWrappers<String> undeclaredThrowableExceptionException(UndeclaredThrowableException e) {
		if(log.isErrorEnabled()) {
			log.error(RespEnum.SERVER_ERROR.getDesc(), e);
		}
		return new BaseWrappers<>(RespEnum.SYSTEM_AUTHENTICATION.getCode(),e.getMessage());
	}

	@ExceptionHandler(NoHandlerFoundException.class)
	@ResponseStatus(HttpStatus.NOT_FOUND)
	public BaseWrappers<String> noHandlerFoundException(NoHandlerFoundException e) {
		if(log.isErrorEnabled()) {
			log.error(RespEnum.SYSTEM_AUTHENTICATION.getDesc(), e.getMessage()+"接口不存在");
		}
		return new BaseWrappers<>(RespEnum.SYSTEM_AUTHENTICATION);
	}

	/**
	 * HTTP解析请求参数异常
	 * @param e
	 * @return
	 */
	@ExceptionHandler(HttpMessageNotReadableException.class)
	public BaseWrappers<String> httpMessageNotReadableException(HttpMessageNotReadableException e) {
		if(log.isErrorEnabled()) {
			log.error(RespEnum.ERROR_MESSAGE.getDesc(), e.getMessage()+"仅支持application/json格式的参数");
		}
		return new BaseWrappers<>(RespEnum.SYSTEM_AUTHENTICATION.getCode(),e.getMessage()+"仅支持application/json格式的参数");
	}

	/**
	 * HTTP
	 * @param e
	 * @return
	 */
	@ExceptionHandler(value = HttpMediaTypeException.class)
	@ResponseStatus(HttpStatus.OK)
	public BaseWrappers<String> httpMediaTypeException(HttpMediaTypeException e) {
		log.error("httpMediaTypeException:",e);
		return new BaseWrappers<>(RespEnum.REQUEST_PARAM_ERROR);
	}
}
